package cc.rengu.oltp.service.realize.impl;

import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.ImageCodeResult;
import cc.rengu.oltp.service.realize.ImageCodeService;
import cc.rengu.oltp.utility.util.ImageCodeUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlConfigUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

import java.lang.reflect.Method;

/**
 * 图片验证码实现类
 * Created by wangcheng on 2021/3/25 9:57
 */
public class ImageCodeServiceImpl implements ImageCodeService {
    RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    private boolean apiCallFlag = false;
    private Class clasz;
    private Object methodInstance;

    public ImageCodeServiceImpl() throws Exception {
        String imageCodeServiceImpl = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.APPLICATION_CONF_NODE, AppConfigConstant.IMAGE_CODE_SERVICE_IMPL);
        String DEFAULT_IMPL = "cc.rengu.oltp.service.realize.impl.ImageCodeServiceImpl";
        if (!StringUtil.isEmptyOrNull(imageCodeServiceImpl) && !DEFAULT_IMPL.equals(imageCodeServiceImpl.trim())) {
            apiCallFlag = true;
            clasz = Class.forName(imageCodeServiceImpl.trim());
            methodInstance = clasz.newInstance();
        }
    }

    @Override
    public ImageCodeResult applyImageCode(String instId, String applySeqNum, Object imageApplyInfo) throws Exception {
        ImageCodeResult<String> imageCodeResult;
        if (apiCallFlag) {
            Method applyImageCodeMethod = clasz.getMethod("applyImageCode", String.class, String.class, Object.class);
            imageCodeResult = (ImageCodeResult<String>) applyImageCodeMethod.invoke(methodInstance, instId, applySeqNum, imageApplyInfo);
        } else {
            ImageCodeUtil imageCodeUtil = new ImageCodeUtil();
            String imageCode = imageCodeUtil.generateImageCode(4);
            imageCodeResult = new ImageCodeResult<>();
            imageCodeResult.setImageType("local");
            imageCodeResult.setApplySeqNum(applySeqNum);
            RedisUtil.hashSet(AppParamConstant.IMAGE_CODE_CACHE, applySeqNum, imageCode.toUpperCase(), 300);
            imageCodeResult.setResult(imageCodeUtil.getImageString("jpg"));
        }
        return imageCodeResult;
    }

    @Override
    public boolean verifyImageCode(String instId, String verifySeqNum, Object imageVerifyInfo) throws Exception {
        if (apiCallFlag) {
            Method verifyImageCodeMethod = clasz.getMethod("verifyImageCode", String.class, String.class, Object.class);
            return (boolean) verifyImageCodeMethod.invoke(methodInstance, instId, verifySeqNum, imageVerifyInfo);
        } else {
            String imageCode = (String) imageVerifyInfo;
            String applyImageCode = RedisUtil.hashGet(AppParamConstant.IMAGE_CODE_CACHE, verifySeqNum);
            if (StringUtil.isEmptyOrNull(applyImageCode)) {
                applyImageCode = verifySeqNum;
            } else {
                RedisUtil.hashDelete(AppParamConstant.IMAGE_CODE_CACHE, verifySeqNum);
            }
            if (StringUtil.isEmptyOrNull(imageCode) || !applyImageCode.equalsIgnoreCase(imageCode)) {
                rglog.error("图片验证码校验失败，申请时的验证码:<{}>,验证时上送的验证码:<{}>", imageCode, applyImageCode);
                return false;
            }
            return true;
        }
    }
}
